package com.ng.common.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtUtil {
	@Value("${jwt.secret}")
	private String secretKey; // 从配置文件中读取密钥
	@Value("${jwt.validity}")
	private long validityInMilliseconds = 3600000; // 1小时
	@Value("${jwt.refresh.validity}")
	private long refreshValidityInMilliseconds = 604800000; // 7天

	public String generateToken(String username) {
		Map<String, Object> claims = new HashMap<>();
		return createToken(claims, username);
	}

	public String generateToken(String username, Map<String, Object> claims) {
		return createToken(claims, username);
	}

	public String generateRefreshToken(String username) {
		Map<String, Object> claims = new HashMap<>();
		return createToken(claims, username, refreshValidityInMilliseconds);
	}

	public String generateRefreshToken(String username, Map<String, Object> claims) {
		return createToken(claims, username, refreshValidityInMilliseconds);
	}

	private String createToken(Map<String, Object> claims, String subject) {
		return createToken(claims, subject, validityInMilliseconds);
	}

	private String createToken(Map<String, Object> claims, String subject, long validity) {
		return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
				.setExpiration(new Date(System.currentTimeMillis() + validity))
				.signWith(SignatureAlgorithm.HS256, secretKey).compact();
	}

	public boolean validateToken(String token, String username) {
		final String extractedUsername = extractUsername(token);
		return (extractedUsername.equals(username) && !isTokenExpired(token));
	}

	public String extractUsername(String token) {
		return extractAllClaims(token).getSubject();
	}

	public Claims extractAllClaims(String token) {
		return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
	}

	private boolean isTokenExpired(String token) {
		return extractAllClaims(token).getExpiration().before(new Date());
	}
}